home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue31 / pathed35 / PATHED35.ZIP / SolutionsUnlimitedPathEd.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-01-03  |  24.9 KB  |  916 lines

  1. {-------------------------------------------------------------------------------
  2. Name                    :    SolutionsUnlimitedPathEd.pas
  3. Author                : Robert Kozak
  4. Date                    : November 1, 1997
  5.  
  6. Copyright            : ⌐ 1997 Solutions Unlimited. All Rights Reserved.
  7.  
  8. Version             : 3.5
  9. Last Updated    : January 1, 1998
  10.  
  11. Description        : This is an expert for managing the Paths in Delphi.
  12.  
  13. Notes:
  14.  
  15. Version History
  16. ===============
  17.  
  18. Version 1.0 - Internal
  19.     - New Search path did not become active until Delphi was restarted.
  20.  
  21. Version 1.5 - Internal 
  22.     - Added Hooks into Delphi to refresh the Search path without restarting.
  23.     - Added the sync with packages option.
  24.  
  25. Version 2.0 - Release version.
  26.     - Added 'Sort' Popup menuitem to alphabetically sort the path list.
  27.     (Anyone actually use this?)
  28.  
  29. Version 2.01 - Internal
  30.     - Fixed a bug that kept adding directories to the list each time it was created.
  31.  
  32. Version 3.02 - Release
  33.     - Removed dependancies on third party components with large runtime Libraries.
  34.      (DPLs are now alot smaller)
  35.     - Added 'Add Sub Dirs' checkbox to the Add Directory.
  36.     - Added AboutBox
  37.  
  38. Version 3.5 - Release
  39.   - Fixed bug with btnUpClick and btnDownClick. It seems the State of an Item
  40.   in a TCheckListBox gets erased when calling the Exchange function. I was using
  41.   Raize custom components before and it worked correctly so I didn't notice this
  42.   until someone brought it to my attention.
  43.   - Added an AddIn Notification so Delphi would notify me when Packages were
  44.   added or removed.
  45.   - Added AddPath and RemovePath procedure to make things easier.
  46.   - Changed the names of the Units in PathEX10 to avoid possible conflicts
  47.  
  48. -------------------------------------------------------------------------------}
  49. unit SolutionsUnlimitedPathEd;
  50.  
  51. interface
  52.  
  53. uses
  54.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  55.   ComCtrls, Registry, StdCtrls, ExptIntf, ToolIntf, ExtCtrls, rkCommon, Menus,
  56.   checklst, SolutionsUnlimitedBrowseFolder, rkAboutForm, SolutionsPlacemnt;
  57.  
  58. const
  59.   DELPHI_3_PATHHISTORY        = '\Software\Borland\Delphi\3.0\HistoryList\hiLibraryPath';
  60.     DELPHI_3_PATH                             = '\Software\Borland\Delphi\3.0\Library\';
  61.     DELPHI_3_FULLPATH                        = '\Software\Borland\Delphi\3.0\Library\FULLPath\';
  62.     DELPHI_3_KNOWN_PACKAGES         = '\Software\Borland\Delphi\3.0\Known Packages';
  63.     DELPHI_3_DISABLED_PACKAGES    = '\Software\Borland\Delphi\3.0\Disabled Packages';
  64.  
  65.   DELPHI_3_SOLUTIONS                    = '\Software\Borland\Delphi\3.0\Solutions\';
  66.     DELPHI_3_PATH_KEY                        = 'SearchPath';
  67.  
  68. type
  69.   TPackageNotifier = class(TIAddInNotifier)
  70.   public
  71.     constructor Create;
  72.     destructor Destroy; override;
  73.     procedure FileNotification(NotifyCode: TFileNotification;
  74.         const FileName: string; var Cancel: Boolean); override; stdcall;
  75.     procedure EventNotification(NotifyCode: TEventNotification;
  76.         var Cancel: Boolean); override; stdcall;
  77.   end;
  78.  
  79.   TPathEdExpert = class(TIExpert)
  80.   private
  81.     fMenuItem: TIMenuItemIntf;
  82.     procedure MenuClick(Sender: TIMenuItemIntf);
  83.     procedure NewWndProc(var Msg : TMessage); virtual;
  84.     protected
  85.         procedure PreProcessMsg(Sender: TObject; var msg: TMessage; var bContinue: Boolean);
  86.     procedure PostProcessMsg(Sender: TObject; var msg: TMessage; var bContinue: Boolean);
  87.         procedure UpdateDelphiPath;
  88.   public
  89.         constructor Create;
  90.     destructor Destroy; override;
  91.     procedure Execute; override;
  92.     function GetAuthor: string; override;
  93.     function GetComment: string; override;
  94.     function GetGlyph: HICON; override;
  95.     function GetIDString: string; override;
  96.     function GetMenuText: string; override;
  97.     function GetName: string; override;
  98.     function GetPage: string; override;
  99.     function GetState: TExpertState; override;
  100.     function GetStyle: TExpertStyle; override;
  101.     property MenuItem: TIMenuItemIntf read fMenuItem;
  102.   end;
  103.  
  104.   TfrmSetPath = class(TForm)
  105.     Panel1: TPanel;
  106.     btnDown: TButton;
  107.     btnAdd: TButton;
  108.     btnUp: TButton;
  109.     btnRemove: TButton;
  110.     StatusBar1: TStatusBar;
  111.     FormStorage: TSUFormStorage;
  112.     pnlList: TPanel;
  113.     btnOptions: TButton;
  114.     PopupMenu1: TPopupMenu;
  115.     Sort1: TMenuItem;
  116.     btnClose: TButton;
  117.     N1: TMenuItem;
  118.     About1: TMenuItem;
  119.     tabPath: TTabSheet;
  120.     lstPath: TCheckListBox;
  121.     procedure btnAddClick(Sender: TObject);
  122.     procedure btnRemoveClick(Sender: TObject);
  123.     procedure btnUpClick(Sender: TObject);
  124.     procedure btnDownClick(Sender: TObject);
  125.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  126.     procedure FormCreate(Sender: TObject);
  127.     procedure FormStorageRestorePlacement(Sender: TObject);
  128.     procedure btnOptionsClick(Sender: TObject);
  129.     procedure Sort1Click(Sender: TObject);
  130.     procedure About1Click(Sender: TObject);
  131.     procedure FormDestroy(Sender: TObject);
  132.   private
  133.     { Private declarations }
  134.     PackageNotifier : TPackageNotifier;
  135.     FDisplayHistory : Boolean;
  136.     FDisplayPackagePath: Boolean;
  137.     FDisplayProject : Boolean;
  138.     FSyncPackages : Boolean;
  139.         OldList : TStringList;
  140.     PackagePath : TStringList;
  141.     procedure SaveList;
  142.     procedure RestoreList;
  143.     function ListSaved : Boolean;
  144.     procedure ParsePath;
  145.       procedure WritePath;
  146.       procedure ReadPath;
  147.     procedure SyncWithPackages;
  148.   protected
  149.     procedure SetDisplayPackagePath(Value : Boolean);
  150.     procedure SetSyncPackages(Value : Boolean);
  151.   public
  152.     { Public declarations }
  153.     property DisplayPackagePath: Boolean read FDisplayPackagePath write SetDisplayPackagePath;
  154.     property SyncPackages : Boolean read FSyncPackages write SetSyncPackages;
  155.   end;
  156.  
  157.     procedure Register;
  158.  
  159. var
  160.   frmSetPath: TfrmSetPath;
  161.     WindowHook : HHook;
  162.   DoSubClass : Boolean;
  163.     PathEdExpert : TPathEdExpert;
  164.   Path : string;
  165.  
  166. procedure AddPath(Path : string);
  167. procedure RemovePath(Path : string);
  168.  
  169. implementation
  170.  
  171. uses
  172.   SolutionsUnlimitedPathOptions;
  173.  
  174. resourcestring
  175.   sName = 'Library Search Path Expert';
  176.   sMenuText = 'Edit Library Search &Path...';
  177.   sMenuName = 'EditLibrarySearchPathItem';
  178.  
  179. {$R *.DFM}
  180.  
  181. var
  182.   NewWndProcPointer : TFarProc;
  183.   OrgWndProcPointer : LongInt;
  184.   WindowHandle : HWnd;
  185.  
  186. procedure AddPath(Path : string);
  187. begin
  188.   // We don't need the last BackSlash
  189.   if AnsiLastChar(Path)^ = '\' then Delete(Path,Length(Path),1);
  190.  
  191.   with frmSetPath.lstPath do
  192.   begin
  193.     if Items.IndexOf(Path) = -1 then Items.Insert(ItemIndex,Path);
  194.     State[Items.IndexOf(Path)] := cbChecked;
  195.     ItemIndex := Items.IndexOf(Path);
  196.   end;
  197. end;
  198.  
  199. {------------------------------------------------------------------------------}
  200.  
  201. procedure RemovePath(Path : string);
  202. var
  203.   OldIndex : Integer;
  204.   PathIndex : Integer;
  205.  
  206. begin
  207.   // We don't need the last BackSlash
  208.   if AnsiLastChar(Path)^ = '\' then Delete(Path,Length(Path),1);
  209.  
  210.     with frmSetPath.lstPath do
  211.   begin
  212.     OldIndex := ItemIndex;
  213.     PathIndex := Items.IndexOf(Path);
  214.         if PathIndex <> -1 then
  215.     begin
  216.       Items.Delete(PathIndex);
  217.  
  218.       Dec(OldIndex);
  219.       if OldIndex < 0 then OldIndex := 0;
  220.       ItemIndex := OldIndex;
  221.     end;
  222.   end;
  223. end;
  224.  
  225. {------------------------------------------------------------------------------}
  226.  
  227. function Hook(Code : Integer; wparam :WPARAM; lParam : LPARAM): LResult; stdcall;
  228. var
  229.     aClassName : array [0..25] of char;
  230.   i: integer;
  231.  
  232. begin
  233.     with TCWPStruct(PCWPStruct(lparam)^) do
  234.       if (Message = WM_ParentNotify) and (LoWord(wparam) = WM_CREATE) then
  235.         begin
  236.              WindowHandle := GetParent(lParam);
  237.       GetClassName(WindowHandle, aClassName, 25);
  238.  
  239.       if (aClassName = 'TEnvDialog') and (DoSubClass) then
  240.       begin
  241.         FlashWindow(Application.MainForm.Handle, False);
  242.         NewWndProcPointer := MakeObjectInstance(PathEdExpert.NewWndProc);
  243.             OrgWndProcPointer := LongInt(SetWindowLong(WindowHandle, gwl_WndProc, LongInt(NewWndProcPointer)));
  244.       end;
  245.       end;
  246.  
  247.     Result := CallNextHookEx(WindowHook, Code, WParam, Lparam);
  248. end;
  249.  
  250. { TPathEdExpert ---------------------------------------------------------------}
  251.  
  252. constructor TPathEdExpert.Create;
  253. var
  254.     Index : integer;
  255.  
  256. begin
  257.   inherited Create;
  258.  
  259.   frmSetPath := TfrmSetPath.Create(nil);
  260.  
  261.   with ToolServices.GetMainMenu.FindMenuItem('InstallPackagesItem') do
  262.   begin
  263.       Index := GetIndex + 1;
  264.         fMenuItem := GetParent.InsertItem(Index,sMenuText,sMenuName,'',0,0,0,[mfEnabled,mfVisible],MenuClick);
  265.   end;
  266.  
  267.   WindowHook := SetWindowsHookEx(WH_CALLWNDPROC, @Hook, HInstance, GetCurrentThreadID);
  268. end;
  269.  
  270. {------------------------------------------------------------------------------}
  271.  
  272. destructor TPathEdExpert.Destroy;
  273. begin
  274.   MenuItem.Free;
  275.  
  276.   frmSetPath.Free;
  277.  
  278.   SetWindowLong(WindowHandle, gwl_WndProc, OrgWndProcPointer);
  279.  
  280.     UnHookWindowsHookEx(WindowHook);
  281.   inherited Destroy;
  282. end;
  283.  
  284. {------------------------------------------------------------------------------}
  285.  
  286. procedure TPathEdExpert.NewWndProc(var Msg : TMessage);
  287. //function NewWndProc(Handle : HWND; Msg : UInt; wparam : WPARAM; lparam: LPARAM): LRESULT; stdcall;
  288. var
  289.     EnvDialog : TCustomForm;
  290.   LibraryTab :  TTabSheet;
  291.  
  292.   PathCombo : TComboBox;
  293.   temp : string;
  294.  
  295. begin
  296.   case Msg.Msg of
  297.     WM_WINDOWPOSCHANGING :
  298.     begin
  299.         TWindowPos(pWindowPos(Msg.Lparam)^).cx := 0;
  300.         TWindowPos(pWindowPos(Msg.Lparam)^).cy := 0;
  301.       Msg.Result := 0;
  302.     end;
  303.  
  304.         CM_ACTIVATE:
  305.           if Application.FindComponent('EnvDialog') <> nil then
  306.         begin
  307.             EnvDialog := TForm(Application.FindComponent('EnvDialog'));
  308.           EnvDialog.ModalResult := mrOK;
  309.            PathCombo := TComboBox(EnvDialog.FindComponent('LibOptionsDlg2').FindComponent('ecLibraryPath'));
  310.         PathCombo.Text := Path;
  311.           PostMessage(EnvDialog.Handle, CM_DEACTIVATE, 0, 0);
  312.         Msg.Result := 0;
  313.         end;
  314.         CM_DEACTIVATE:
  315.           if Application.FindComponent('EnvDialog') <> nil then
  316.         begin
  317.           EnvDialog := TForm(Application.FindComponent('EnvDialog'));
  318.           EnvDialog.ModalResult := mrOK;
  319.         Msg.Result := 0;
  320.         end;
  321.  
  322. //  else Result := CallWindowProc(Pointer(OrgWndProcPointer), Handle, Msg, wparam, lparam);
  323.   else Dispatch(Msg);
  324.   end;
  325. end;
  326.  
  327. {------------------------------------------------------------------------------}
  328.  
  329. procedure TPathEdExpert.MenuClick(Sender:
  330.    TIMenuItemIntf);
  331. begin
  332.   Execute;
  333. end;
  334.  
  335. {------------------------------------------------------------------------------}
  336.  
  337. function TPathEdExpert.GetStyle: TExpertStyle;
  338. begin
  339.   Result := esAddIn;
  340. end;
  341.  
  342. {------------------------------------------------------------------------------}
  343.  
  344. function TPathEdExpert.GetName: string;
  345. begin
  346.   Result := sName;
  347. end;
  348.  
  349. {------------------------------------------------------------------------------}
  350.  
  351. function TPathEdExpert.GetIDString: string;
  352. begin
  353.   Result := 'Solutions Unlimited.PathEditor';
  354. end;
  355.  
  356. {------------------------------------------------------------------------------}
  357.  
  358. procedure TPathEdExpert.Execute;
  359. begin
  360.     frmSetPath.ShowModal;
  361.  
  362.   UpdateDelphiPath;
  363. end;
  364.  
  365. {------------------------------------------------------------------------------}
  366.  
  367. procedure TPathEdExpert.PreProcessMsg(Sender: TObject;
  368.   var msg: TMessage; var bContinue: Boolean);
  369. begin
  370.      case msg.msg of
  371.     WM_WINDOWPOSCHANGING :
  372.     begin
  373.         TWindowPos(pWindowPos(Msg.Lparam)^).cx := 0;
  374.         TWindowPos(pWindowPos(Msg.Lparam)^).cy := 0;
  375.     end;
  376.   end;
  377. end;
  378.  
  379. {------------------------------------------------------------------------------}
  380.  
  381. procedure TPathEdExpert.PostProcessMsg(Sender: TObject;
  382.   var msg: TMessage; var bContinue: Boolean);
  383. var
  384.     EnvDialog : TCustomForm;
  385.   LibraryTab :  TTabSheet;
  386.  
  387.   PathCombo : TComboBox;
  388.   temp : string;
  389.  
  390. begin
  391.   // Hard coding the Component Names for this release. Will create a wrapper Class
  392.   // for Delphi in the next release.
  393.     case Msg.Msg of
  394.         CM_ACTIVATE:
  395.           if Application.FindComponent('EnvDialog') <> nil then
  396.         begin
  397.             EnvDialog := TForm(Application.FindComponent('EnvDialog'));
  398.           EnvDialog.ModalResult := mrOK;
  399.           PathCombo := TComboBox(EnvDialog.FindComponent('LibOptionsDlg2').FindComponent('ecLibraryPath'));
  400.         PathCombo.Text := Path;
  401.           PostMessage(EnvDialog.Handle, CM_DEACTIVATE, 0, 0);
  402.         end;
  403.         CM_DEACTIVATE:
  404.           if Application.FindComponent('EnvDialog') <> nil then
  405.         begin
  406.           EnvDialog := TForm(Application.FindComponent('EnvDialog'));
  407.           EnvDialog.ModalResult := mrOK;
  408.         end;
  409.     end;
  410. end;
  411.  
  412. procedure TPathEdExpert.UpdateDelphiPath;
  413. var
  414.     ABuilder : TForm;
  415.   EnvDialogItem : TMenuItem;
  416.  
  417. begin
  418.     DoSubClass := True;
  419.   if Assigned(Application.FindComponent('AppBuilder')) then
  420.   begin
  421.       ABuilder := TForm(Application.FindComponent('AppBuilder'));
  422.     if Assigned(ABuilder.FindComponent('ToolsOptionsItem')) then
  423.     begin
  424.           EnvDialogItem := TMenuItem(ABuilder.FindComponent('ToolsOptionsItem'));
  425.             EnvDialogItem.Click;
  426.         DoSubClass := False;
  427.       end;
  428.     end;
  429. end;
  430.  
  431. // These methods are not important for an AddIn expert;
  432. {------------------------------------------------------------------------------}
  433.  
  434. function TPathEdExpert.GetAuthor: string;
  435. begin
  436.     Result := ''
  437. end;
  438.  
  439. {------------------------------------------------------------------------------}
  440.  
  441. function TPathEdExpert.GetComment: string;
  442. begin
  443.     Result := ''
  444. end;
  445.  
  446. {------------------------------------------------------------------------------}
  447.  
  448. function TPathEdExpert.GetGlyph: HICON;
  449. begin
  450.     Result := 0
  451. end;
  452.  
  453. {------------------------------------------------------------------------------}
  454.  
  455. function TPathEdExpert.GetMenuText: string;
  456. begin
  457.     Result := '';
  458. end;
  459.  
  460. {------------------------------------------------------------------------------}
  461.  
  462. function TPathEdExpert.GetPage: string;
  463. begin
  464.     Result := ''
  465. end;
  466.  
  467. {------------------------------------------------------------------------------}
  468.  
  469. function TPathEdExpert.GetState: TExpertState;
  470. begin
  471.     Result := []
  472. end;
  473.  
  474. { TPackageNotifier ------------------------------------------------------------}
  475.  
  476. constructor TPackageNotifier.Create;
  477. begin
  478.   inherited Create;
  479.  
  480.   if not ToolServices.AddNotifierEx(Self)
  481.   then raise Exception.Create('Can''t Add Package Notifier');
  482. end;
  483.  
  484. {------------------------------------------------------------------------------}
  485.  
  486. destructor TPackageNotifier.Destroy;
  487. begin
  488.   ToolServices.RemoveNotifier(Self);
  489.  
  490.   inherited Destroy;
  491. end;
  492.  
  493. {------------------------------------------------------------------------------}
  494.  
  495. procedure TPackageNotifier.FileNotification(NotifyCode: TFileNotification;
  496.     const FileName: string; var Cancel: Boolean);
  497. begin
  498.   case NotifyCode of
  499.     fnPackageInstalled    : AddPath(ExtractFilePath(FileName));
  500.     fnPackageUninstalled  : RemovePath(ExtractFilePath(FileName));
  501.   end;
  502. end;
  503.  
  504. {------------------------------------------------------------------------------}
  505.  
  506. procedure TPackageNotifier.EventNotification(NotifyCode: TEventNotification;
  507.     var Cancel: Boolean);
  508. begin
  509.  {Don't Do anything here. Must be overriden because this is an Abstract Method
  510.  but we don't need it for Package notifications}
  511. end;
  512.  
  513. { TfrmSetPath -----------------------------------------------------------------}
  514.  
  515. procedure TfrmSetPath.SaveList;
  516. var
  517.  i : Integer;
  518.  
  519. begin
  520.     OldList.Clear;
  521.     for i := 0 to lstPath.Items.Count-1 do
  522.       OldList.AddObject(lstPath.Items[i],Pointer(Ord(lstPath.State[i])));
  523. end;
  524.  
  525. {------------------------------------------------------------------------------}
  526.  
  527. procedure TfrmSetPath.RestoreList;
  528. var
  529.  i : Integer;
  530.  
  531. begin
  532.     lstPath.Clear;
  533.     for i := 0 to OldList.Count-1 do
  534.   begin
  535.       lstPath.Items.Add(OldList[i]);
  536.     lstPath.State[i] := TCheckBoxState(OldList.Objects[i]);
  537.   end;
  538. end;
  539.  
  540. {------------------------------------------------------------------------------}
  541.  
  542. function TfrmSetPath.ListSaved : Boolean;
  543. begin
  544.     Result := OldList.Count > 0;
  545. end;
  546.  
  547. {------------------------------------------------------------------------------}
  548.  
  549. procedure TfrmSetPath.ParsePath;
  550. var
  551.     s, x : string;
  552.  
  553. begin
  554.     s := '';
  555.   x := '';
  556.  
  557.   with TRegistry.Create do
  558.   try
  559.       RootKey := HKEY_CURRENT_USER;
  560.     OpenKey(DELPHI_3_PATH, False);
  561.         s := ReadString(DELPHI_3_PATH_KEY);
  562.  
  563.     while s <> '' do
  564.     begin
  565.       lstPath.Items.Add(strToken(s,';'));
  566.       lstPath.State[lstPath.Items.Count-1] := cbChecked
  567.     end;
  568.   finally
  569.       Free;
  570.   end;
  571. end;
  572.  
  573. {------------------------------------------------------------------------------}
  574.  
  575. procedure TfrmSetPath.WritePath;
  576. var
  577.   i : Integer;
  578.   b : string;
  579.  
  580. begin
  581.     Path := '';
  582.  
  583.     for i := 0 to lstPath.Items.Count-1 do
  584.         if lstPath.State[i] = cbChecked then Path := Path + lstPath.Items[i] + ';';
  585.  
  586.     Path := Copy(Path,1,Length(Path)-1);
  587.  
  588.   with TRegistry.Create do
  589.   try
  590.       RootKey := HKEY_CURRENT_USER;
  591.     if not OpenKey(DELPHI_3_PATH,False) then Exit;
  592.     if not ValueExists(DELPHI_3_PATH_KEY) then Exit;
  593.  
  594.        WriteString(DELPHI_3_PATH_KEY, Path);
  595.  
  596.     // Clear out the values. Then Add them in.
  597.        DeleteKey(DELPHI_3_FULLPATH);
  598.        OpenKey(DELPHI_3_FULLPATH, True);
  599.         for i := 0 to lstPath.Items.Count-1 do
  600.     begin
  601.         if lstPath.State[i] = cbChecked
  602.       then b := 'T'
  603.       else b := 'F';
  604.  
  605.         WriteString(IntToStr(i),lstPath.Items[i]+','+b);
  606.     end;
  607.   finally
  608.       Free;
  609.   end;
  610. end;
  611.  
  612. {------------------------------------------------------------------------------}
  613.  
  614. procedure TfrmSetPath.ReadPath;
  615. var
  616.     s : string;
  617.   b: Boolean;
  618.     i : Integer;
  619.   KeyInfo : TRegKeyInfo;
  620.  
  621. begin
  622.     lstPath.Clear;
  623.  
  624.   with TRegistry.Create do
  625.   try
  626.       RootKey := HKEY_CURRENT_USER;
  627.     if not OpenKey(DELPHI_3_FULLPATH,False) then
  628.     begin
  629.         ParsePath;
  630.         Exit;
  631.         end;
  632.  
  633.         GetKeyInfo(KeyInfo);
  634.  
  635.         for i := 0 to KeyInfo.NumValues-1 do
  636.     begin
  637.         s := ReadString(IntToStr(i));
  638.         b := (Copy(s,Pos(',',s)+1,1) = 'T');
  639.         s := Copy(s,1,Pos(',',s)-1);
  640.         lstPath.Items.Add(s);
  641.             if b then lstPath.State[i] := cbChecked;
  642.     end;
  643.   finally
  644.       Free;
  645.   end;
  646. end;
  647.  
  648. {------------------------------------------------------------------------------}
  649.  
  650. procedure TfrmSetPath.SyncWithPackages;
  651. var
  652.   i : Integer;
  653.     s : string;
  654.  
  655. begin
  656.      SaveList;
  657.  
  658.   PackagePath.Clear;
  659.     with TRegistry.Create do
  660.   try
  661.  
  662.       RootKey := HKEY_CURRENT_USER;
  663.     if not OpenKey(DELPHI_3_KNOWN_PACKAGES,False) then Exit;
  664.  
  665.     GetValueNames(PackagePath);
  666.  
  667.     if DisplayPackagePath then
  668.           for i := 0 to PackagePath.Count-1 do
  669.         with PackagePath do
  670.         begin
  671.             s := ExtractFilePath(PackagePath[i]);
  672.           s := Copy(s,1,Length(s)-1);
  673.               if lstPath.Items.IndexOf(s) = -1 then
  674.           begin
  675.               Add(s);
  676.             lstPath.Items.Add(s);
  677.                       lstPath.State[lstPath.Items.Count-1] := cbChecked;
  678.           end;
  679.         end;
  680.   finally
  681.       Free;
  682.   end;
  683. end;
  684.  
  685. {------------------------------------------------------------------------------}
  686.  
  687. procedure TfrmSetPath.SetDisplayPackagePath(Value : Boolean);
  688. begin
  689.   if FDisplayPackagePath <> Value then
  690.   begin
  691.     FDisplayPackagePath := Value;
  692.   end;
  693. end;
  694.  
  695. {------------------------------------------------------------------------------}
  696.  
  697. procedure TfrmSetPath.SetSyncPackages(Value : Boolean);
  698. begin
  699.   if FSyncPackages <> Value then
  700.   begin
  701.     FSyncPackages := Value;
  702.  
  703.     if FSyncPackages
  704.     then
  705.     begin
  706.       SyncWithPackages;
  707.       if PackageNotifier = nil then PackAgeNotifier := TPackageNotifier.Create;
  708.     end
  709.     else
  710.     begin
  711.       if PackageNotifier <> nil then
  712.       begin
  713.         PackAgeNotifier.Free;
  714.         PackageNotifier := nil;
  715.       end;
  716.       if ListSaved then RestoreList;
  717.     end;
  718.   end;
  719. end;
  720.  
  721. {------------------------------------------------------------------------------}
  722.  
  723. procedure TfrmSetPath.btnAddClick(Sender: TObject);
  724. var
  725.     s : string;
  726.   sl : TStringList;
  727.   i : Integer;
  728.  
  729. begin
  730.   with TBrowseFolder.Create(nil) do
  731.   try
  732.     Title := 'Add Directory to Library Search Path';
  733.     ShowPathInStatusArea := True;
  734.     CustomButtonVisible := True;
  735.     CustomButtonCaption := 'Add Sub Directories';
  736.     CustomButtonType := btCheckBox;
  737.     CustomButtonWidth := 150;
  738.       if Execute then
  739.           with lstPath do
  740.       begin
  741.         if ItemIndex < 0 then ItemIndex := 0;
  742.         // Adding SubDirs?
  743.         if CustomButtonChecked then
  744.         begin
  745.           sl := TStringList.Create;
  746.           sl.Clear;
  747.           try
  748.             ReadDirectoryNames(Directory+'\', sl);
  749.             for i := sl.Count-1 downto 0 do
  750.             begin
  751.               s := Directory+'\'+sl[i];
  752.               AddPath(s);
  753. {                if Items.IndexOf(s) = -1 then Items.Insert(ItemIndex,s);
  754.               State[Items.IndexOf(s)] := cbChecked;
  755.               ItemIndex := Items.IndexOf(s);}
  756.             end;
  757.           finally
  758.             sl.Free;
  759.           end;
  760.         end;
  761.  
  762.         s := Directory;
  763.         AddPath(s);
  764. {          if Items.IndexOf(s) = -1 then Items.Insert(ItemIndex,s);
  765.         State[Items.IndexOf(s)] := cbChecked;
  766.         ItemIndex := Items.IndexOf(s);}
  767.       end;
  768.   finally
  769.     SetFocus;
  770.     Free;
  771.   end;
  772.  
  773.   StatusBar1.SimpleText := 'Path has been updated.';
  774. end;
  775.  
  776. {------------------------------------------------------------------------------}
  777.  
  778. procedure TfrmSetPath.btnRemoveClick(Sender: TObject);
  779. var
  780.   OldIndex : Integer;
  781.  
  782. begin
  783.   with lstPath do RemovePath(Items[ItemIndex]);
  784.  
  785.     {with lstPath do
  786.   begin
  787.     OldIndex := ItemIndex;
  788.         if ItemIndex > -1 then Items.Delete(ItemIndex);
  789.  
  790.     Dec(OldIndex);
  791.     if OldIndex < 0 then OldIndex := 0;
  792.     ItemIndex := OldIndex;
  793.   end;}
  794.  
  795.   StatusBar1.SimpleText := 'Path has been updated.';
  796. end;
  797.  
  798. {------------------------------------------------------------------------------}
  799.  
  800. procedure TfrmSetPath.btnUpClick(Sender: TObject);
  801. var
  802.     s : string;
  803.   SaveState1 : TCheckBoxState;
  804.   SaveState2 : TCheckBoxState;
  805.  
  806. begin
  807.     with lstPath do
  808.         if ItemIndex > 0 then
  809.     begin
  810.         s := Items[ItemIndex];
  811.  
  812.       SaveState1 := lstPath.State[ItemIndex];
  813.       SaveState2 := lstPath.State[ItemIndex-1];
  814.  
  815.         Items.Exchange(ItemIndex, ItemIndex-1);
  816.  
  817.       lstPath.State[ItemIndex] := SaveState2;
  818.       lstPath.State[ItemIndex-1] := SaveState1;
  819.  
  820.       ItemIndex := Items.IndexOf(s);
  821.       SetFocus;
  822.     end;
  823. end;
  824.  
  825. {------------------------------------------------------------------------------}
  826.  
  827. procedure TfrmSetPath.btnDownClick(Sender: TObject);
  828. var
  829.     s : string;
  830.   SaveState1 : TCheckBoxState;
  831.   SaveState2 : TCheckBoxState;
  832.  
  833. begin
  834.     with lstPath do
  835.         if ItemIndex < Items.Count-1 then
  836.     begin
  837.         s := Items[ItemIndex];
  838.  
  839.       SaveState1 := lstPath.State[ItemIndex];
  840.       SaveState2 := lstPath.State[ItemIndex+1];
  841.  
  842.         Items.Exchange(ItemIndex, ItemIndex+1);
  843.  
  844.       lstPath.State[ItemIndex] := SaveState2;
  845.       lstPath.State[ItemIndex+1] := SaveState1;
  846.  
  847.       ItemIndex := Items.IndexOf(s);
  848.       SetFocus;
  849.     end;
  850. end;
  851.  
  852. {------------------------------------------------------------------------------}
  853.  
  854. procedure TfrmSetPath.FormClose(Sender: TObject; var Action: TCloseAction);
  855. begin
  856.     WritePath;
  857. end;
  858.  
  859. {------------------------------------------------------------------------------}
  860.  
  861. procedure TfrmSetPath.FormCreate(Sender: TObject);
  862. begin
  863.   PackageNotifier := nil;
  864.  
  865.     OldList := TStringList.Create;
  866.   OldList.Clear;
  867.     ReadPath;
  868.  
  869.   PackagePath := TStringList.Create;
  870. end;
  871.  
  872. {------------------------------------------------------------------------------}
  873.  
  874. procedure TfrmSetPath.FormStorageRestorePlacement(Sender: TObject);
  875. begin
  876.   with TRegistry.Create do
  877.   try
  878.       RootKey := HKEY_CURRENT_USER;
  879.     if not OpenKey(FormStorage.IniFileName+'\'+FormStorage.IniSection,False) then
  880.     begin
  881.         Exit;
  882.         end;
  883.  
  884.     if ValueExists('cbxDisplayPackages_Checked') then
  885.       FDisplayPackagePath := (ReadString('cbxDisplayPackages_Checked') = 'True');
  886.  
  887.     if ValueExists('cbxSync_Checked') then
  888.           SyncPackages := (ReadString('cbxSync_Checked') = 'True');
  889.   finally
  890.     Free;
  891.   end;
  892. end;
  893.  
  894. {------------------------------------------------------------------------------}
  895.  
  896. procedure Register;
  897. begin
  898.     PathEdExpert := TPathEdExpert.Create;
  899.   RegisterLibraryExpert(PathEdExpert);
  900. end;
  901.  
  902. {------------------------------------------------------------------------------}
  903.  
  904. procedure TfrmSetPath.btnOptionsClick(Sender: TObject);
  905. begin
  906.   with TfrmPathOptions.Create(nil) do
  907.   try
  908.     if ShowModal = mrOK then
  909.     begin
  910.       DisplayPackagePath  := cbxDisplayPackages.Checked;
  911.       SyncPackages        := cbxSync.Checked;
  912.     end;
  913.   finally
  914.     Free;
  915.   end;
  916. end;
  917.  
  918. {------------------------------------------------------------------------------}
  919.  
  920. procedure TfrmSetPath.Sort1Click(Sender: TObject);
  921. begin
  922.   lstPath.Sorted := True;
  923. end;
  924.  
  925. procedure TfrmSetPath.About1Click(Sender: TObject);
  926. begin
  927.   with TfrmrkAbout.Create(nil) do
  928.   try
  929.     Copyright := '⌐ Copyright 1997 Robert N. Kozak. All Rights Reserved.';
  930.     Version := 'Version 3.5';
  931.     AppName := 'Delphi Library Search Path Editor';
  932.     Title := 'About Delphi Library Search Path Editor';
  933.     SecretMessage := 'You found the Secret Message!';
  934.     ShowModal;
  935.   finally
  936.     Free;
  937.   end;
  938. end;
  939.  
  940. procedure TfrmSetPath.FormDestroy(Sender: TObject);
  941. begin
  942.   if PackageNotifier <> nil then PackageNotifier.Free;
  943.  
  944.     OldList.Free;
  945.   PackagePath.Free;
  946. end;
  947.  
  948. end.
  949.  
  950.